#ifndef _KLAS_DATA_HPP_
#define _KLAS_DATA_HPP_

#include "../include/Defines.hpp"
#include <string>
#include <map>
using namespace std;


namespace klas
{
  //! All objects returned by Data are derived from DataObject.
  /*! This, I believe, allows type safe data management. */
  class DataObject
  {
    public:

      //! Dtor.
      virtual ~DataObject();

      //! Gets if the data object is valid.
      /*! \return True if the data is valid, false if not. */
      virtual bool isValid() const = 0;

      //! Returns the type of object.
      /*! \return An ID of the object type.  Use Data:: to compare. */
      virtual iReal getObjectType() const = 0;

      //! Cleans up the object's memory.
      /*! \return True if the cleanup was a success, false if not. */
      virtual bool kill() = 0;


    protected:

      //! Is the data valid?
      bool m_isValid;

  };


	//! Data stores external data and makes it easily accessible.
	class Data
	{
		public:
			
			//! Ctor.
			Data();
			
			//! Dtor.  Deletes all loaded data.
			~Data();
			
			//! Loads in data.
			/*! \param key The key to associate this data with.
					\param file The path of the data to load.
					\param type The type of file to load.  Accessible with Data::type
					\return Success or failure of loading the data. */
      bool load(string key, string file, iReal type=INVALID_DATA);
			
			//! Returns data.
			/*! \param key The key that the data is associated with.
          \return Returns a DataObject* of the data.  Returns InvalidData() if the key
									doesn't exist. */
      DataObject* get(string key);
			
			//! Checks if a key has been used.
			/*! \param key The key to check.
					\return Returns true if the key is associated with some type of data. */
			bool has(string key);
			
			//! A enum of the types of files that can be loaded in.
      enum TYPES { INVALID_DATA, TEXTURE, FONT, MUSIC, SOUND_EFFECT };
			
			
		private:
			
      //! A map of keys to data objects, representing our data.
      map<string, DataObject*> m_data;
      DataObject* m_invalidData;
	};


  //! This class represents invalid data.
  /*! All this class should be used for is for error checking. */
  class InvalidData : public DataObject
  {
    public:

      //! Ctor.
      InvalidData();

      //! Dtor.
      ~InvalidData();

      //! Returns false.
      /*! \return Always false. */
      virtual bool isValid() const;

      //! Gets the object type.
      /*! \return Returns Data::INVALID_DATA. */
      virtual iReal getObjectType() const;

      //! Does nothing.
      /*! \return Always false. */
      virtual bool kill();

  };

}

#endif
